home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / devBlockDevice.c < prev    next >
C/C++ Source or Header  |  1991-08-11  |  9KB  |  278 lines

  1. /* 
  2.  * devBlockDevice.c --
  3.  *
  4.  *    Routines supporting the interface to Sprite block devices.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/dev/RCS/devBlockDevice.c,v 9.1 90/09/11 12:16:12 rab Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20.  
  21. #include "sprite.h"
  22. #include "fs.h"
  23. #include "devBlockDevice.h"
  24. #include "devFsOpTable.h"
  25. #include "sync.h"
  26.  
  27. static void syncDoneProc _ARGS_((DevBlockDeviceRequest *requestPtr,
  28.     ReturnStatus status, int amountTransferred));
  29.  
  30.  
  31. /*
  32.  *----------------------------------------------------------------------
  33.  *
  34.  * Dev_BlockDeviceAttach --
  35.  *
  36.  *    Build data structures necessary for accessing a block device.
  37.  *    This routine interprets the type field of the Fs_Device structure
  38.  *    and calls the appropriate attach routine. 
  39.  *
  40.  * Results:
  41.  *    A pointer to a DevBlockDeviceHandle structure for the device. 
  42.  *    NIL if the device can not be attached.
  43.  *
  44.  * Side effects:
  45.  *    Device dependent.
  46.  *
  47.  *----------------------------------------------------------------------
  48.  */
  49. DevBlockDeviceHandle *
  50. Dev_BlockDeviceAttach(devicePtr)
  51.     Fs_Device    *devicePtr;    /* The device to attach. */
  52. {
  53.  
  54.     int    type = DEV_TYPE_INDEX(devicePtr->type);
  55.     /*
  56.      * If type is out of range or the device type as no block IO 
  57.      * capabilities then give up. Otherwise we let the Device Attach
  58.      * procedure file the device.
  59.      */
  60.     if ((type >= devNumDevices) ||
  61.     (devFsOpTable[type].blockDevAttach == DEV_NO_ATTACH_PROC)) {
  62.     return ((DevBlockDeviceHandle *) NIL);
  63.     }
  64.     return ((devFsOpTable[type].blockDevAttach)(devicePtr));
  65. }
  66.  
  67.  
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * Dev_BlockDeviceRelease --
  72.  *
  73.  *    Release an attached block device. Resources held by the device 
  74.  *    should be freed.
  75.  *
  76.  * Results:
  77.  *    A Sprite return Status specifying it the device could be releases.
  78.  *
  79.  * Side effects:
  80.  *    Device dependent.
  81.  *
  82.  *----------------------------------------------------------------------
  83.  */
  84. ReturnStatus
  85. Dev_BlockDeviceRelease(blockDevHandlePtr)
  86.      DevBlockDeviceHandle
  87.         *blockDevHandlePtr;  /* Handle of the device to releaes */
  88. {
  89.     return (blockDevHandlePtr->releaseProc)(blockDevHandlePtr);
  90.  
  91. }
  92.  
  93.  
  94. /*
  95.  *----------------------------------------------------------------------
  96.  *
  97.  * Dev_BlockDeviceIO --
  98.  *
  99.  *    Enqueue a block IO request for the specified device. Upon operation
  100.  *    completion doneProc will be called. 
  101.  *
  102.  *     NOTE: The DevBlockDeviceRequest structure pointed to by the requestPtr
  103.  *          argument is assumed to remain valid and unchanged until the
  104.  *          doneProc specified in DevBlockDeviceRequest is called.
  105.  *
  106.  * Results:
  107.  *    SUCCESS if operation is sucessfully enqueued. 
  108.  *    A Sprite error code otherwise.
  109.  *
  110.  * Side effects:
  111.  *    The specified doneProc is called with the following arguments:
  112.  *
  113.  *    (*doneProc)(requestPtr, returnStatus, amountTransferred)
  114.  *        DevBlockDeviceRequest    *requestPtr;   
  115.  *                           / * The requestPtr passed to
  116.  *                         * Dev_BlockDeviceIO. * /
  117.  *        ReturnStatus    returnStatus;  / * The error status of the
  118.  *                         * command. SUCCESS if no
  119.  *                         * error occured. * /
  120.  *        int    amountTransferred;     / * The number of blocks
  121.  *                         * transfered by the 
  122.  *                         * operation. * /
  123.  *----------------------------------------------------------------------
  124.  * Because of its simplicity and in an attempt to reduce procedure calling
  125.  * depth, Dev_BlockDeviceIO may be coded as an macro in devBlockDevice.h.
  126.  */
  127. #ifndef Dev_BlockDeviceIO
  128. ReturnStatus 
  129. Dev_BlockDeviceIO(blockDevHandlePtr, requestPtr)
  130.     DevBlockDeviceHandle
  131.         *blockDevHandlePtr;  /* Handle of the device to operate on. */
  132.     DevBlockDeviceRequest
  133.         *requestPtr;         /* Request to be performed. */
  134. {
  135.     return (blockDevHandlePtr->blockIOProc)(blockDevHandlePtr, requestPtr);
  136. }
  137. #endif /* Dev_BlockDeviceIO */
  138.  
  139. /*
  140.  *----------------------------------------------------------------------
  141.  *
  142.  * Dev_BlockDeviceIOControl --
  143.  *
  144.  *    Execute an IO control operation on the specified device.
  145.  *
  146.  * Results:
  147.  *    SUCCESS if operation is successful. 
  148.  *    An error status otherwise.
  149.  *
  150.  * Side effects:
  151.  *    Device dependent.
  152.  *
  153.  *----------------------------------------------------------------------
  154.  * Because of its simplicity and in an attempt to reduce procedure calling
  155.  * depth, Dev_BlockDeviceIOControl may be coded as an macro in devBlockDevice.h.
  156.  */
  157. #ifndef    Dev_BlockDeviceIOControl
  158. ReturnStatus 
  159. Dev_BlockDeviceIOControl(blockDevHandlePtr, ioctlPtr, replyPtr) 
  160.     DevBlockDeviceHandle
  161.         *blockDevHandlePtr;  /* Handle of the device to operate on. */
  162.     Fs_IOCParam *ioctlPtr;    /* Standard I/O Control parameter block */
  163.     Fs_IOReply *replyPtr;    /* outBuffer length and returned signal */
  164. {
  165.  
  166.     return (blockDevHandlePtr->IOControlProc)(blockDevHandlePtr, ioctlPtr, replyPtr);
  167.  
  168.  
  169. }
  170. #endif /* Dev_BlockDeviceIOControl */
  171. /*
  172.  * The following structure and routines are used to implement the routine
  173.  * Dev_BlockDeviceIOSync.
  174.  * The arguments to Dev_BlockDeviceIOSync are stored in a SyncCmdBuf on 
  175.  * the caller's stack and  Dev_BlockDeviceIO is called. The call back function
  176.  * syncDoneProc fills in the OUT arguments are wakes the caller.
  177.  *
  178.  */
  179. typedef struct SyncCmdBuf {
  180.     Sync_Semaphore mutex;      /* Lock for synronizing updates of 
  181.                    * this structure with the call back 
  182.                    * function. */
  183.     Sync_Condition wait;      /* Condition valued used to wait for
  184.                    * callback. */
  185.     Boolean      done;          /* Is the operation finished or not? */
  186.     int      amountTransferred;       /* Number of bytes transferred according
  187.                    * to the call back. */
  188.     ReturnStatus status;       /* Operation return status according to 
  189.                    * call back. */
  190. } SyncCmdBuf;
  191.  
  192. /*
  193.  *----------------------------------------------------------------------
  194.  *
  195.  * syncDoneProc --
  196.  *
  197.  *    This procedure is called when a sync block command started by 
  198.  *    Dev_BlockDeviceIO finished. It's calling sequence is 
  199.  *    defined by the call back caused by the Dev_BlockDeviceIO routine.
  200.  *
  201.  * Results:
  202.  *    None.
  203.  *
  204.  * Side effects:
  205.  *    SyncCmdBuf is filled in and a wakeup is broadcast.
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209.  
  210. static void
  211. syncDoneProc(requestPtr, status, amountTransferred)
  212.     DevBlockDeviceRequest    *requestPtr;
  213.     ReturnStatus status;
  214.     int    amountTransferred;
  215. {
  216.     SyncCmdBuf    *syncCmdDataPtr = (SyncCmdBuf *) (requestPtr->clientData);
  217.     /*
  218.      * A pointer to a SyncCmdBuf is passed as the clientData to this call.
  219.      * Lock the structure, fill in the return values and wake up the
  220.      * initiator.
  221.      */
  222.     MASTER_LOCK(&syncCmdDataPtr->mutex);
  223.     syncCmdDataPtr->status = status;
  224.     syncCmdDataPtr->amountTransferred = amountTransferred;
  225.     syncCmdDataPtr->done = TRUE;
  226.     Sync_MasterBroadcast(&syncCmdDataPtr->wait);
  227.     MASTER_UNLOCK(&syncCmdDataPtr->mutex);
  228.     return;
  229. }
  230.  
  231. /*
  232.  *----------------------------------------------------------------------
  233.  *
  234.  * Dev_BlockDeviceIOSync --
  235.  *
  236.  *    Perform a block IO request for the specified device and wait 
  237.  *    for completion.
  238.  *
  239.  * Results:
  240.  *    SUCCESS if operation is successful completed. 
  241.  *    A Sprite error code otherwise.
  242.  *
  243.  * Side effects:
  244.  *    Device specific block IO done.
  245.  *----------------------------------------------------------------------
  246.  */
  247. ReturnStatus 
  248. Dev_BlockDeviceIOSync(blockDevHandlePtr, requestPtr,amountTransferredPtr)
  249.     DevBlockDeviceHandle
  250.         *blockDevHandlePtr;  /* Handle of the device to operate on. */
  251.     DevBlockDeviceRequest 
  252.         *requestPtr;         /* Request to block IO device. */
  253.     int    *amountTransferredPtr;          /* Area to store number of bytes
  254.                       * transferred. May be NIL. */
  255. {
  256.     ReturnStatus status;
  257.     SyncCmdBuf     syncCmdData;
  258.  
  259.     requestPtr->clientData = (ClientData) &syncCmdData;
  260.     requestPtr->doneProc = syncDoneProc;
  261.     Sync_SemInitDynamic((&syncCmdData.mutex),"BlockSyncCmdMutex");
  262.     syncCmdData.done = FALSE;
  263.     syncCmdData.amountTransferred = 0;
  264.     status = Dev_BlockDeviceIO(blockDevHandlePtr, requestPtr);
  265.     if (status == SUCCESS) {
  266.     MASTER_LOCK((&syncCmdData.mutex));
  267.     while (syncCmdData.done == FALSE) { 
  268.         Sync_MasterWait((&syncCmdData.wait),(&syncCmdData.mutex),FALSE);
  269.     }
  270.     MASTER_UNLOCK((&syncCmdData.mutex));
  271.     status = syncCmdData.status;
  272.     } 
  273.     if (amountTransferredPtr != (int *) NIL) { 
  274.     *amountTransferredPtr = syncCmdData.amountTransferred;
  275.     }
  276.     return (status);
  277. }
  278.